package com.lingyuan.oms.controller;


import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.lingyuan.common.core.domain.R;
import com.lingyuan.common.core.domain.vo.oms.OrderVo;
import com.lingyuan.common.core.exception.ServiceException;
import com.lingyuan.common.core.utils.DateUtils;
import com.lingyuan.common.core.utils.uuid.UUID;
import com.lingyuan.common.core.web.controller.BaseController;
import com.lingyuan.common.security.service.TokenService;
import com.lingyuan.oms.annotation.Idempotent;
import com.lingyuan.oms.constant.*;
import com.lingyuan.oms.domain.OrderEntity;
import com.lingyuan.oms.domain.param.CreateOrderParam;
import com.lingyuan.oms.domain.param.SettleAccountsParam;
import com.lingyuan.oms.domain.response.SettleAccountsResponse;
import com.lingyuan.oms.factory.HandlerFactory;
import com.lingyuan.oms.handler.ChainOfResponsibility;
import com.lingyuan.oms.service.OrderService;
import com.lingyuan.system.api.model.LoginUser;
import lombok.extern.log4j.Log4j2;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

/**
 * @ClassName：OrderController
 * @Author: LeiHao
 * @Date: 2024/9/18 10:08
 * @Description: 订单控制层
 */
@Log4j2
@RestController
@RequestMapping("/order")
public class OrderController extends BaseController {
    @Autowired
    private OrderService orderService;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private HandlerFactory handlerFactory;


    /* *
     * @Title: getRedisOrder
     * @Author: DELL
     * @Date: 2024-09-27 11:32:25
     * @Params: [selectOrderToken]
     * @Return: R<OrderEntity>
     * @Description: 查询redis订单信息
     */
    @GetMapping("/getRedisOrder/{selectOrderToken}")
    public R<OrderEntity> getRedisOrder(@PathVariable String selectOrderToken) {
        OrderEntity orderEntity = orderService.getRedisOrder(selectOrderToken);
        if (orderEntity == null) {
            return R.fail();
        }
        return R.ok(orderEntity);
    }

    /* *
     * @Title: paymentOrder
     * @Author: DELL
     * @Date: 2024-09-27 11:32:25
     * @Params: [selectOrderToken]
     * @Return: R
     * @Description: 发送消息
     */
    @GetMapping("/paymentOrder/{selectOrderToken}")
    public R paymentOrder(@PathVariable String selectOrderToken) {
//        订单添加做接口合并
        String orderStr = stringRedisTemplate.opsForValue().get(OrderConstant.SUBMIT_ORDER_KEY + selectOrderToken);
        OrderEntity orderEntity = JSON.parseObject(orderStr, OrderEntity.class);
        //用户在15分钟内完成支付订单
        if (orderEntity.getSyncDb() == 0) {
            orderService.syncRedisOrder(selectOrderToken);
        }
        rabbitTemplate.convertAndSend(RabbitMqConstant.EXCHANGE_PAYMENT_NAME, RabbitMqConstant.QUEUE_PAYMENT_DEAD_NAME, selectOrderToken, message -> {
            message.getMessageProperties().setMessageId(com.lingyuan.common.core.utils.uuid.UUID.randomUUID().toString());
            return message;
        });
        return R.ok();
    }

    /* *
     * @Title: createOrder
     * @Author: DELL
     * @Date: 2024-09-21 11:49:13
     * @Params: [createOrderParam]
     * @Return: R
     * @Description: 生成订单
     */
    @PostMapping("createOrder")
    @Idempotent(value = "token")
    public R createOrder(@RequestBody CreateOrderParam createOrderParam) {
        long startTime = System.currentTimeMillis();

        LoginUser loginUser = tokenService.getLoginUser();
        createOrderParam.setUserId(loginUser.getUserid());
        //参数校验
        // 构建责任链
        ChainOfResponsibility chain = new ChainOfResponsibility(
                handlerFactory,
                HandlerType.ADDRESS_HANDLER,
                HandlerType.SKU_IDS_HANDLER,
                HandlerType.CART_ITEM_STOCK_HANDLER);
        // 执行责任链处理
        boolean result = chain.process(createOrderParam);
        if (!result) {
            throw new ServiceException("参数异常!请刷新页面重试");
        }
        // 用户信息 and 订单号
        String orderSn = getOrderSn(loginUser);
        setUserInfoAndOrderSn(loginUser, createOrderParam, orderSn);
        rabbitTemplate.convertAndSend(RabbitMqConstant.EXCHANGE_SUBMIT_NAME, RabbitMqConstant.QUEUE_SUBMIT_DEAD_NAME, JSON.toJSONString(createOrderParam), message -> {
            message.getMessageProperties().setMessageId(UUID.randomUUID().toString());
            return message;
        });
        long endTime = System.currentTimeMillis();
        System.out.println("===========================================生成订单耗时:" + (endTime - startTime) + "ms========================================");
        return R.ok(orderSn, "下单中......");
    }

    /**
     * 设置用户信息封装下单参数
     * @param loginUser
     * @param createOrderParam
     * @param orderSn
     */
    private void setUserInfoAndOrderSn(LoginUser loginUser, CreateOrderParam createOrderParam, String orderSn) {
        Long userid = loginUser.getUserid();
        String username = loginUser.getUsername();
        createOrderParam.setUserId(userid);
        createOrderParam.setUserName(username);
        createOrderParam.setOrderSn(orderSn);
    }

    /**
     * 生成订单号
     *
     * @return
     */
    private String getOrderSn(LoginUser loginUser) {
        Long userId = loginUser.getUserid();
        String orderSn = "XN"
                + DateUtils.dateNow()
                + IdUtil.getSnowflake(1, 1).nextIdStr().substring(13)
                + String.format("%05d", userId.intValue());
        return orderSn;
    }
    /* *
     * @Title: settleAccounts
     * @Author: DELL
     * @Date: 2024-09-21 11:49:13
     * @Params: [settleAccountsParam]
     * @Return: R<SettleAccountsResponse>
     * @Description: 结算
     */
    @PostMapping("settleAccounts")
    public R<SettleAccountsResponse> settleAccounts(@RequestBody SettleAccountsParam settleAccountsParam) {
        SettleAccountsResponse settleAccountsResponse = orderService.settleAccounts(settleAccountsParam);
        return R.ok(settleAccountsResponse, "下单成功");
    }

    /**
     * 根据订单id查询订单信息
     * @param orderId
     * @return
     */
    @GetMapping("/findByOrderId/{orderId}")
    public R<OrderVo> findByOrderId(@PathVariable("orderId") Long orderId) {
        OrderEntity orderEntity = orderService.findOrderId(orderId);
        OrderVo orderVo = new OrderVo();
        BeanUtils.copyProperties(orderEntity, orderVo);
        return R.ok(orderVo);
    }


}
